import "./index.css";
import type { OptionsType } from "./type";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { useDark, isNumber, isFunction, useResizeObserver } from "@pureadmin/utils";
import { type PropType, h, ref, toRef, watch, nextTick, defineComponent, getCurrentInstance } from "vue";

const props = {
    options: {
        type: Array<OptionsType>,
        default: () => []
    },
    /** 默认选中，按照第一个索引为 `0` 的模式，可选（`modelValue`只有传`number`类型时才为响应式） */
    modelValue: {
        type: undefined,
        require: false,
        default: "0"
    },
    /** 将宽度调整为父元素宽度	 */
    block: {
        type: Boolean,
        default: false
    },
    /** 控件尺寸 */
    size: {
        type: String as PropType<"small" | "default" | "large">
    },
    /** 是否全局禁用，默认 `false` */
    disabled: {
        type: Boolean,
        default: false
    },
    /** 当内容发生变化时，设置 `resize` 可使其自适应容器位置 */
    resize: {
        type: Boolean,
        default: false
    }
};

export default defineComponent({
    name: "ReSegmented",
    props,
    emits: ["change", "update:modelValue"],
    setup(props, { emit }) {
        const width = ref(0);
        const translateX = ref(0);
        const { isDark } = useDark();
        const initStatus = ref(false);
        const curMouseActive = ref(-1);
        const segmentedItembg = ref("");
        const instance = getCurrentInstance()!;
        const curIndex = isNumber(props.modelValue) ? toRef(props, "modelValue") : ref(0);

        function handleChange({ option, index }, event: Event) {
            if (props.disabled || option.disabled) return;
            event.preventDefault();
            isNumber(props.modelValue) ? emit("update:modelValue", index) : (curIndex.value = index);
            segmentedItembg.value = "";
            emit("change", { index, option });
        }

        function handleMouseenter({ option, index }, event: Event) {
            if (props.disabled) return;
            event.preventDefault();
            curMouseActive.value = index;
            if (option.disabled || curIndex.value === index) {
                segmentedItembg.value = "";
            } else {
                segmentedItembg.value = isDark.value ? "#1f1f1f" : "rgba(0, 0, 0, 0.06)";
            }
        }

        function handleMouseleave(_, event: Event) {
            if (props.disabled) return;
            event.preventDefault();
            curMouseActive.value = -1;
        }

        function handleInit(index = curIndex.value) {
            nextTick(() => {
                const curLabelRef = instance?.proxy?.$refs[`labelRef${index}`] as ElRef;
                if (!curLabelRef) return;
                width.value = curLabelRef.clientWidth;
                translateX.value = curLabelRef.offsetLeft;
                initStatus.value = true;
            });
        }

        function handleResizeInit() {
            useResizeObserver(".pure-segmented", () => {
                nextTick(() => {
                    handleInit(curIndex.value);
                });
            });
        }

        (props.block || props.resize) && handleResizeInit();

        watch(
            () => curIndex.value,
            index => {
                nextTick(() => {
                    handleInit(index);
                });
            },
            {
                immediate: true
            }
        );

        watch(() => props.size, handleResizeInit, {
            immediate: true
        });

        const rendLabel = () => {
            return props.options.map((option, index) => {
                return (
                    <label
                        ref={`labelRef${index}`}
                        class={[
                            "pure-segmented-item",
                            (props.disabled || option?.disabled) && "pure-segmented-item-disabled"
                        ]}
                        style={{
                            background: curMouseActive.value === index ? segmentedItembg.value : "",
                            color: props.disabled
                                ? null
                                : !option.disabled && (curIndex.value === index || curMouseActive.value === index)
                                  ? isDark.value
                                      ? "rgba(255, 255, 255, 0.85)"
                                      : "rgba(0,0,0,.88)"
                                  : ""
                        }}
                        onMouseenter={event => handleMouseenter({ option, index }, event)}
                        onMouseleave={event => handleMouseleave({ option, index }, event)}
                        onClick={event => handleChange({ option, index }, event)}
                    >
                        <input type="radio" name="segmented" />
                        <div
                            class="pure-segmented-item-label"
                            v-tippy={{
                                content: option?.tip,
                                zIndex: 41000
                            }}
                        >
                            {option.icon && !isFunction(option.label) ? (
                                <span
                                    class="pure-segmented-item-icon"
                                    style={{ marginRight: option.label ? "6px" : 0 }}
                                >
                                    {h(
                                        useRenderIcon(option.icon, {
                                            ...option?.iconAttrs
                                        })
                                    )}
                                </span>
                            ) : null}
                            {option.label ? (
                                isFunction(option.label) ? (
                                    h(option.label)
                                ) : (
                                    <span>{option.label}</span>
                                )
                            ) : null}
                        </div>
                    </label>
                );
            });
        };

        return () => (
            <div
                class={{
                    "pure-segmented": true,
                    "pure-segmented-block": props.block,
                    "pure-segmented--large": props.size === "large",
                    "pure-segmented--small": props.size === "small"
                }}
            >
                <div class="pure-segmented-group">
                    <div
                        class="pure-segmented-item-selected"
                        style={{
                            width: `${width.value}px`,
                            transform: `translateX(${translateX.value}px)`,
                            display: initStatus.value ? "block" : "none"
                        }}
                    ></div>
                    {rendLabel()}
                </div>
            </div>
        );
    }
});
